import { CydonElement, define, Directive, directives } from 'cydon'
import stringToColor from '../utils/colorize'
import { API, Tag } from '../api'
import { getTag } from '../models/tag'
import { countColor, sizeNum } from '../utils/helper'
import { CAutoComplete } from './CAutoComplete'

export const [postview] = document.getElementsByTagName('post-view')

@define('tag-item')
export class TagItem extends CydonElement {
	/** 类别 */
	category = ''
	/** 创建者 */
	creator = ''
	/** 标签 */
	tag = <Tag>{ name: '' }

	get name() { return this.tag.name }
	set name(value) {
		this.tag.name = value
		getTag(value).then(async tag => {
			if (tag) {
				tag.count += (await API.getTagCountDelta(value))[0]
				this.data.tag = tag
			}
		})
	}

	/** 标签使用数 */
	get count() { return this.tag.count }

	/** 标签使用数缩写 */
	get num() { return sizeNum(this.count) }

	/** 上边框样式 */
	get borderTop() {
		return '0'
	}

	/** 左边框样式 */
	get borderLeft() {
		return '0'
	}

	/** 下边框样式 */
	get borderBottom() {
		return '0'
	}

	/** 右边框样式 */
	get borderRight() {
		return '0'
	}

	/** 背景颜色 */
	get bgColor() {
		// TODO: 优化
		return tagRE(this.name).test(postview.expr) ? '#ffb' :
			tagRE('-' + this.name).test(postview.expr) ? '#def' : 'none'
	}

	/** 标签颜色 */
	get color() {
		return '#' + stringToColor(this.name)
	}

	/** 使用数颜色 */
	get countColor() {
		return '#' + countColor(this.count, 0, this.tag.created_at)
	}

	/** 字体大小 */
	get fontSize() {
		return Math.min(2.3 * Math.log2((this.count | 0) + 16) + 4, 24) + 'px'
	}

	/** 其他样式（加粗、斜体等） */
	get fontStyle() {
		return ''
	}

	connectedCallback() {
		let ac = <CAutoComplete>this.parentElement?.parentElement
		if (ac?.tagName != 'C-AUTO-COMPLETE')
			ac = <CAutoComplete>document.querySelector('#content c-auto-complete')
		// 添加指令
		if (this.$directives == directives)
			this.$directives = [(name, value): Directive | void => {
				if (name == 'highlight') {
					return {
						deps: new Set,
						f(el: HTMLElement) {
							const html = highlight(this[value], ac.text)
							el.innerHTML = html
						},
					}
				}
			}, ...directives]
		super.connectedCallback()
	}

	/** 将标签添加到搜索 */
	addSearch(e: Event) {
		e.preventDefault()
		this.updateValue('name')
		const expr = postview.expr
		const s = expr.replace(tagRE('-' + this.name), '')
		postview.data.expr = (expr == s ? s + ' ' + this.name : s).trimStart()
	}

	/** 将反向标签添加到搜索 */
	addInvSearch(e: Event) {
		e.preventDefault()
		this.updateValue('name')
		const expr = postview.expr
		const s = expr.replace(tagRE(this.name), '')
		postview.data.expr = (expr == s ? s + ' -' + this.name : s).trimStart()
	}

	/** 删除标签 */
	removeTag(e: Event) {
		e.preventDefault()
		const tags = postview.sidebar.tags
		tags.splice(tags.indexOf(this.name), 1)
	}
}

declare global {
	interface HTMLElementTagNameMap {
		'tag-item': TagItem
	}
}

/** escape special characters for RegExp */
const escapeRE = (s: string) => s.replace(/[.*+?^${}()[\]\\]/g, '\\$&')

const tagRE = (name: string) =>
	RegExp(`(\\s+|^)${escapeRE(name)}(\\s+|$)`, 'g')

/** highlight text */
const highlight = (name: string, text: string) =>
	text ? name.replace(RegExp(escapeRE(text), 'gi'), `<mark>${text}</mark>`)
		: name

